﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text;

namespace Acoris.Document
{
    /// <summary>
    /// 表示一个文本段落
    /// </summary>
    public class TextSegment : IContentSegment
    {
        private string m_text = string.Empty;
        private object m_lock = new object();
        private IContentFormat m_format;

        /// <summary>
        /// 获取或设置当前文本段落的内容
        /// </summary>
        public string Text {
            get { return m_text; }
            set { m_text = value; }
        }

        /// <summary>
        /// 获取或设置当前文本段落的格式
        /// </summary>
        public IContentFormat Format {
            get { return m_format; }
        }

        /// <summary>
        /// 获取当前文本段落内容的长度
        /// </summary>
        public int Length {
            get { return m_text.Length; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        /// <param name="content"></param>
        public void ReplaceRange(int offset, int count, IContentSegment content)
        {
            Debug.Assert(content is TextSegment);
            Debug.Assert(offset + count <= m_text.Length);

            lock (m_lock) {
                var textSegment = (TextSegment)content;
                var newText = textSegment.Text;

                if (offset == 0 && count == m_text.Length) {
                    m_text = newText;
                }
                else {
                    if (offset != 0) {
                        var left = m_text.Substring(0,offset - 0);
                        var right = m_text.Substring(offset + count,m_text.Length - count - offset);
                        m_text = string.Concat(string.Concat(left, newText), right);
                    }
                    else {
                        var right = m_text.Substring(offset + count,m_text.Length - count);
                        m_text = string.Concat(newText, right);
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        public void RemoveRange(int offset, int count)
        {
            lock (m_lock) {
                if (offset == 0 && count == m_text.Length) {
                    m_text = string.Empty;
                }
                else {
                    if (offset == 0) {
                        m_text = m_text.Substring(count, m_text.Length - count);
                    }
                    else {
                        var left = m_text.Substring(0,offset);
                        var right = m_text.Substring( offset + count,m_text.Length - offset-count);
                        m_text = string.Concat(left, right);
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="format"></param>
        public void ApplyFormat(IContentFormat format)
        {
            VerifyInput(format);
            m_format = format;
        }

        public void ClearFormat()
        {
            m_format = null;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="format"></param>
        internal void VerifyInput(IContentFormat format)
        {
            Debug.Assert(format != null);
            Debug.Assert(format is TextFormat);
        }

        /// <summary>
        /// 分割指定位置的内容
        /// </summary>
        /// <param name="offset"></param>
        /// <returns></returns>
        public IContentSegment Split(int offset)
        {
            Debug.Assert(offset < m_text.Length);

            if(offset == 0) {
                return this;
            }
            else {
                var left = m_text.Substring(0,offset);
                var right = m_text.Substring(offset,m_text.Length - offset);
                m_text = left;
                return new TextSegment
                {
                    m_text = right
                };
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="offset"></param>
        /// <param name="content"></param>
        public void InsertRange(int offset, IContentSegment content)
        {
            Debug.Assert(content is TextSegment);
            Debug.Assert(offset >= 0 && offset <= m_text.Length);
            var textSegment = content as TextSegment;
            var newText = textSegment.Text;
            if (offset == 0) {
                m_text = newText;
            }
            else if(offset == m_text.Length) {
                m_text = string.Concat(m_text, newText);
            }
            else {
                var left = m_text.Substring(0,offset);
                var right = m_text.Substring(offset,m_text.Length - offset);
                m_text = string.Concat(string.Concat(left, newText), right);
            }
        }

         #region Override

        /// <summary>
        /// 获取与当前对象等价的字符串形式
        /// </summary>
        /// <returns>返回与当前对象等价的字符串形式</returns>
        public override string ToString()
        {
            return m_text.ToString();
        }

        /// <summary>
        /// 获取当前对象与指定对象之间的等价性
        /// </summary>
        /// <param name="obj">指定要比较的对象</param>
        /// <returns>如果两个对象之间等价则返回true，否则返回false</returns>
        public override bool Equals(object obj)
        {
            if(obj is TextSegment segment) {
                return segment.m_text == this.m_text;
            }
            return false;
        }

        /// <summary>
        /// 获取当前对象的哈希值
        /// </summary>
        /// <returns>返回当前对象的哈希值</returns>
        public override int GetHashCode()
        {
            return base.GetHashCode() ^ this.m_text.GetHashCode();
        }

        #endregion
    }
}
